/*
 * IORNN.h
 *
 *  Created on: Dec 17, 2014
 *      Author: Phong
 */

#ifndef IORNN_H_
#define IORNN_H_

#include "cblas.h"
#include <vector>
#include <unordered_set>
#include "Param.h"
#include "Matrix.h"
#include "Default.h"
#include "Deptree.h"
#include "Treebank.h"

using namespace std;

class IORNN {
public:
	Dictionary *vocaDic, *posDic, *deprelDic;
	int dim, wdim;
	int completeInside;
	Param *params;

	IORNN(int dim, Dictionary* vocaDic, Dictionary* posDic, Dictionary* deprelDic,
			vector<Matrix*>& L, int cmplInside);
    ~IORNN();

	void initParam(vector<Matrix*>& L);
    
    void save(string fname);
    
    static IORNN* load(string fname);

	Param* createGrad();

	static Matrix* func(Matrix* X);

	static Matrix* funcPrime(Matrix* F);

	static Matrix* sigmoid(Matrix* X);

	void forwardInside(Deptree* tree);

	real forwardOutside(Deptree* tree);

	void backpropOutside(Deptree* tree, Param* grad, int cmplInside);

	void backpropInside(Deptree* tree, Param* grad, int cmplInside);

	vector<real> computeLogProb(vector<Deptree*>& trees);

    void** computeCostAndGrad(Treebank* tb, int startId, int endId, Param** grad);

	// make sure gradients are computed correctly
	void checkGradient(Treebank* tb);
    
private:
    IORNN() {}

};

#endif /* IORNN_H_ */
